package com.abu.kpaymodel.controller;


import cn.hutool.core.util.IdUtil;
import com.abu.kpaymodel.aliconfig.AliPayTemplate;
import com.abu.kpaymodel.aliconfig.PayAsyncVo;
import com.abu.kpaymodel.aliconfig.PayParam;
import com.abu.kpaymodel.wxconfig.WxPayTemplate;
import com.abu.kpaymodel.wxconfig.WxPayVo;
import com.alibaba.fastjson.JSON;
import com.github.wxpay.sdk.WXPayUtil;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.SortedMap;
import java.util.UUID;

@Slf4j
@RestController
@RequestMapping("pay")
public class PayController {

    @Autowired
    private AliPayTemplate payTemplate;

    @Autowired
    private WxPayTemplate wxPayTemplate;

    /**
     * 支付宝支付
     * @return
     */
    @GetMapping("alipay")
    public String alipay() {
        PayParam payParam = new PayParam();
        payParam.setOut_trade_no(IdUtil.createSnowflake(1,1).nextIdStr());        //订单id不能重复
        payParam.setTotal_amount("10");
        payParam.setSubject("康康小社团");
        payParam.setBody("支付平台");
        String returnUrl = this.payTemplate.alipay(payParam);
        if (StringUtils.isBlank(returnUrl)) {
            return null;
        }
        return returnUrl;
    }

    /**
     * 支付宝回调
     * @param payAsyncVo
     */
    @PostMapping("/ali/notify")
    public void notify(PayAsyncVo payAsyncVo) {
        log.info("异步接收的参数为");
        log.info(payAsyncVo.toString());  //生成的唯一订单标识（商户号+订单号）
    }

    /**
     * 微信支付
     * @param response
     */
    @GetMapping("wxpay")
    public void wxpay(HttpServletResponse response) {
        WxPayVo wxPayVo = new WxPayVo();
        //订单编号要唯一(此处使用hutool工具中的id模拟唯一订单编号)
        wxPayVo.setOut_trade_no(IdUtil.createSnowflake(1,1).nextIdStr());
        wxPayVo.setBody("微信支付平台");
        wxPayVo.setProduct_id("123456");
        wxPayVo.setTotal_fee("1");

//      获取codeUrl，通过codeUrl获取二维码
        String codeUrl = this.wxPayTemplate.getCodeUrl(wxPayVo);
        if (StringUtils.isBlank(codeUrl)) {
            throw new RuntimeException("获取codeUrl失败");
        }
//      3、通过google工具生成二维码供用户扫码支付
        try {
            //3、1生成二维码配置
            Map<EncodeHintType, Object> hints = new HashMap<>();

            //3、2设置纠错等级
            hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);

            //3、3编码类型
            hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");

            BitMatrix bitMatrix = new MultiFormatWriter().encode(codeUrl, BarcodeFormat.QR_CODE, 300, 300, hints);
            OutputStream out = response.getOutputStream();
            MatrixToImageWriter.writeToStream(bitMatrix, "png", out);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 微信支付回调
     * 这里在统一下单中提供的notify_url地址是:http://xsyt2z.natappfree.cc/pay/wx/notify
     */
    @PostMapping("/wx/notify")
    public void orderCallback(HttpServletRequest request) throws Exception {
        InputStream inputStream = request.getInputStream();
        //BufferedReader是包装设计模式，性能更搞
        BufferedReader in = new BufferedReader(new InputStreamReader(inputStream, "UTF-8"));
        StringBuffer sb = new StringBuffer();
        //1、将微信回调信息转为字符串
        String line;
        while ((line = in.readLine()) != null) {
            sb.append(line);
        }
        in.close();
        inputStream.close();
        //2、将xml格式字符串格式转为map集合
        Map<String, String> callbackMap = WXPayUtil.xmlToMap(sb.toString());
        log.info(callbackMap.get("out_trade_no"));
    }

}
